#pragma once

#include <iostream>
#include "Fail.hpp"
#include "Sock.hpp"
#include "Protocol.hpp"

using namespace std;

enum stat
{
    LEFT,
    RIGHT,
    OPER
};

class TcpClient
{
public:
    TcpClient(string server_ip, uint16_t server_port): _server_ip(server_ip), _server_port(server_port)
    {}

    void Init()
    {
        _sock.Socket();
    }

    void Start()
    {

        _sock.Connect(_server_ip, _server_port);
        while(true)
        {
            string inbuffer;
            task(inbuffer);
        }
    }

    //"10+20" --> struct Request
    Request ParseMsg(const string& msg)
    {
        int i = 0;
        int status = LEFT;

        string left;
        string right;
        char op;
        while(i < msg.size())
        {
            if(isdigit(msg[i]) && status == LEFT)
            {
                left += msg[i++];
            }
            else if(isdigit(msg[i]) && status == RIGHT)
            {
                right += msg[i++];
            }
            else
            {
                status = RIGHT;
                op = msg[i++];
            }
        }
        
        Request req;
        req._x = stoi(left);
        req._y = stoi(right);
        req._op = op;

        return req;
    }

    void task(string inbuffer)
    {
        //数据输入
        cout << "Enter>";
        string msg;
        getline(cin, msg);
        
        Request req = ParseMsg(msg); //数据结构化

        cout << "Request: " << req._x << req._op << req._y << endl; //输出请求
        
        //序列化数据
        string send_msg;
        req.Serialize(send_msg);

        //给数据添加报头
        send_msg = AddHeaders(send_msg);

        send(_sock.GetSock(), send_msg.c_str(), send_msg.size(), 0); //发送给服务端

        //接收处理过后的结果
        string package;
contin:
        int n = ReadPackage(_sock.GetSock(), inbuffer, package);
        //读取失败
        if(n == -1)
        {
            return;
        }
        //没读完整
        else if(n == 0)
        {
            goto contin; //继续读,直到数据读取完整
        }

        package = SubHeaders(package, n); //去报头

        cout << package << endl;
        //反序列化
        Response res;
        res.Deserialize(package);

        cout << "result: " << res._result << " code: " << res._code << endl; //结果输出
    }

    ~TcpClient()
    {}
public:
    string _server_ip; 
    uint16_t _server_port;
    Sock _sock;
};